
package java.util;

import java.util.function.Predicate;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

/**
 * 集合层次结构中的 根界面
 * @see     Set
 * @see     List
 * @see     Map
 * @see     SortedSet
 * @see     SortedMap
 * @see     HashSet
 * @see     TreeSet
 * @see     ArrayList
 * @see     LinkedList
 * @see     Vector
 * @see     Collections
 * @see     Arrays
 * @see     AbstractCollection
 * @since 1.2
 */

public interface Collection<E> extends Iterable<E> {
    // Query Operations

    /**
     * 返回此集合中的元素数。 如果此收藏包含超过Integer.MAX_VALUE个元素，则返回Integer.MAX_VALUE 。
     * @return 此集合中的元素数
     */
    int size();

    /**
     * 如果此集合不包含元素，则返回 true
     * @return 如果此集合不包含元素
     */
    boolean isEmpty();

    /**
     * 如果此集合包含指定的元素，则返回true 。
     * 更正式地，返回true如果且仅当该集合至少包含一个元素e使得(o==null ? e==null : o.equals(e))
     *
     * @param o 要在此集合中存在的元素要进行测试
     * @return true如果此集合包含指定的元素
     * @throws ClassCastException 如果指定元素的类型与此集合不兼容（ optional ）
     * @throws NullPointerException 如果指定的元素为空，并且此集合不允许空元素（ optional ）
     */
    boolean contains(Object o);

    /**
     * 返回此集合中的元素的迭代器。
     * 没有关于元素返回顺序的保证（除非这个集合是提供保证的某个类的实例）。
     * @return 一个 Iterator在这个集合中的元素
     */
    Iterator<E> iterator();

    /**
     * 返回一个包含此集合中所有元素的数组。
     * 如果此集合对其迭代器返回的元素的顺序做出任何保证，则此方法必须以相同的顺序返回元素。
     * 返回的数组将是“安全的”，因为该集合不保留对它的引用。
     * （换句话说，这个方法必须分配一个新的数组，即使这个集合是由数组支持的）。 因此，调用者可以自由地修改返回的数组。
     * 此方法充当基于阵列和基于集合的API之间的桥梁。
     * @return 一个包含此集合中所有元素的数组
     */
    Object[] toArray();

    /**
     * 1、返回包含此集合中所有元素的数组;
     * 返回的数组的运行时类型是指定数组的运行时类型。
     * 如果集合适合指定的数组，则返回其中。 否则，将为指定数组的运行时类型和此集合的大小分配一个新数组。
     *
     * 2、如果此集合适合指定的数组，并具有剩余空间（即，该数组具有比此集合更多的元素），则紧跟在集合结束后的数组中的元素将设置为null 。
     * （ 仅当调用者知道此集合不包含任何null元素时，这才有助于确定此集合的长度。）
     *
     * 3、假设x是一个已知只包含字符串的集合。 以下代码可用于将集合转储到新分配的数组中： String ：
     * String[] y = x.toArray(new String[0]);
     * 请注意， toArray(new Object[0])的功能与toArray()相同 。
     *
     * @param <T> 包含集合的数组的运行时类型
     * @param a 要存储此集合的元素的数组，如果它足够大; 否则，为此目的分配相同运行时类型的新数组
     * @return 一个包含此集合中所有元素的数组
     *
     * @throws ArrayStoreException 如果指定数组的运行时类型不是此集合中每个元素的运行时类型的超类型
     * @throws NullPointerException 如果指定的数组为空 is null
     */
    <T> T[] toArray(T[] a);

    // Modification Operations

    /**
     * 确保此集合包含指定的元素（可选操作）
     * 如果此集合由于调用而更改，则返回true
     * 如果此集合不允许重复，并且已包含指定的元素，则返回false
     *
     * 支持此操作的集合可能会限制可能添加到此集合的元素
     * 特别是一些集合拒绝添加null种元素，和其他人将强加可添加元素的类型限制。
     * 收集类应在其文档中明确说明可能添加哪些元素的限制。
     *
     * 如果一个集合拒绝添加一个特定的元素，除了它已经包含该元素之外，它必须抛出异常（而不是返回false ）。
     * 这保留了一个集合在此调用返回后始终包含指定元素的不变量。
     *
     * @param e 要确保在此集合中的存在的元素
     * @return true如果此集合由于调用而更改
     * @throws UnsupportedOperationException 如果此 集合不支持add操作
     * @throws ClassCastException        如果指定元素的类阻止将其添加到此集合
     * @throws NullPointerException      如果指定的元素为空，并且该集合不允许空元素
     * @throws IllegalArgumentException  如果元素的某些属性阻止其添加到此集合
     * @throws IllegalStateException     如果由于插入限制，此时无法添加该元素
     */
    boolean add(E e);

    /**
     * 从该集合中删除指定元素的单个实例（如果存在）（可选操作）。
     * 更正式地，删除元素e ，使得(o==null ? e==null : o.equals(e))
     * 如果该集合包含一个或多个这样的元素。 如果此集合包含指定的元素（或等效地，如果此集合由于调用而更改），则返回true
     *
     * @param o 要从此集合中删除的元素（如果存在）
     * @return true如果一个元素因此调用而被删除
     *
     * @throws ClassCastException   如果指定元素的类型与此集合不兼容（ optional ）
     * @throws NullPointerException 如果指定的元素为空，并且此集合不允许空元素（ optional ）
     * @throws UnsupportedOperationException 如果此 集合不支持remove操作
     */
    boolean remove(Object o);


    // Bulk Operations

    /**
     * 如果此集合包含指定 集合中的所有元素，则返回true。
     *
     * @param  c - 要在此集合中检查遏制的集合
     * @return true如果此集合包含指定集合中的所有元素
     * @throws ClassCastException 如果指定集合中的一个或多个元素的类型与此集合不兼容（ optional ）
     * @throws NullPointerException 如果指定的集合包含一个或多个空元素，并且此集合不允许空元素（ optional ），或者指定的集合为空
     * @see    #contains(Object)
     */
    boolean containsAll(Collection<?> c);

    /**
     * 将指定集合中的所有元素添加到此集合（可选操作）。
     * 如果在操作进行中修改了指定的集合，则此操作的行为是未定义的。
     * （这意味着如果指定的集合是此集合，此调用的行为是未定义的，并且此集合是非空的。）
     *
     * @param c 包含要添加到此集合的元素的集合
     * @return true如果此收集因呼叫而更改
     * @throws UnsupportedOperationException 如果此 集合不支持addAll操作
     * @throws ClassCastException            如果指定集合的元素的类阻止将其添加到此集合
     * @throws NullPointerException          如果指定的集合包含一个空元素，并且此集合不允许空元素，或者如果指定的集合为空
     * @throws IllegalArgumentException      如果指定集合的元素的某些属性阻止其添加到此集合
     * @throws IllegalStateException         如果不是所有的元素可以在此时由于插入限制添加
     * @see #add(Object)
     */
    boolean addAll(Collection<? extends E> c);

    /**
     * 删除指定集合中包含的所有此集合的元素（可选操作）。
     * 此调用返回后，此集合将不包含与指定集合相同的元素。
     *
     * @param c 包含要从此集合中删除的元素的集合
     * @return true如果此集合由于调用而更改
     * @throws UnsupportedOperationException  如果此 集合不支持 removeAll方法
     * @throws ClassCastException   如果此集合中的一个或多个元素的类型与指定的集合不兼容（ optional ）
     * @throws NullPointerException 如果此集合包含一个或多个空元素，并且指定的集合不支持空元素（ optional ），或者如果指定的集合为空
     * @see #remove(Object)
     * @see #contains(Object)
     */
    boolean removeAll(Collection<?> c);

    /**
     * 删除满足给定谓词的此集合的所有元素。 在迭代或谓词中抛出的错误或运行时异常被转发给调用者。
     *
     * 默认实现使用其iterator()遍历集合的所有元素。
     * 使用Iterator.remove()删除每个匹配元素。
     * 如果集合的迭代器不支持删除，那么UnsupportedOperationException将被抛出第一个匹配元素。
     *
     * @param filter 对要删除的元素返回 true
     * @return true如果有任何元素被删除
     * @throws NullPointerException           如果指定的过滤器为空
     * @throws UnsupportedOperationException  如果元素无法从此集合中删除。 如果不能删除匹配的元素，或者一般来说，不支持删除，则实现可能会抛出此异常。
     * @since 1.8
     */
    default boolean removeIf(Predicate<? super E> filter) {
        Objects.requireNonNull(filter);
        boolean removed = false;
        final Iterator<E> each = iterator();
        while (each.hasNext()) {
            if (filter.test(each.next())) {
                each.remove();
                removed = true;
            }
        }
        return removed;
    }

    /**
     * 仅保留此集合中包含在指定集合中的元素（可选操作）。 换句话说，从该集合中删除所有不包含在指定集合中的元素。
     *
     * @param c  包含要保留在此集合中的元素的集合
     * @return true如果此收集因呼叫而更改
     * @throws UnsupportedOperationException   如果此 集合不支持retainAll操作
     * @throws ClassCastException              如果此集合中的一个或多个元素的类型与指定的集合不兼容（ optional ）
     * @throws NullPointerException            如果此集合包含一个或多个空元素，并且指定的集合不允许空元素（ optional ），或者如果指定的集合为空
     * @see #remove(Object)
     * @see #contains(Object)
     */
    boolean retainAll(Collection<?> c);

    /**
     * 从此集合中删除所有元素（可选操作）。 此方法返回后，集合将为空。
     * @throws UnsupportedOperationException 如果此 集合不支持clear操作
     */
    void clear();


    // Comparison and hashing

    /**
     * 将指定的对象与此集合进行比较以获得相等性。
     *
     * 虽然Collection接口不会增加规定向工程总承包为Object.equals，
     * 谁落实Collection接口程序员“直接”（换句话说，创建一个类，是Collection，但不是一个Set或List），
     * 如果必须小心谨慎，他们选择覆盖Object.equals 。
     * 没有必要这样做，最简单的行动是依靠Object的实现，但实施者可能希望实现“价值比较”来代替默认的“参考比较”。 （ List和Set接口要求这样的价值比较。）
     *
     * Object.equals方法的一般合同规定，等于必须是对称的（换句话说， a.equals(b)当且仅当b.equals(a) ）。
     * List.equals和Set.equals的合同规定列表仅等于其他列表，并设置为其他集合。
     * 因此，一个既不实现List也不实现Set接口的集合类的自定义equals方法必须返回false，当该集合与任何列表或集合进行比较时。 （通过相同的逻辑，不可能编写一个正确实现Set和List接口的类。）
     *
     * @param o 要与此集合相等的对象进行比较
     * @return true如果指定的对象等于此集合
     *
     * @see Object#equals(Object)
     * @see Set#equals(Object)
     * @see List#equals(Object)
     */
    boolean equals(Object o);

    /**
     * 返回此集合的哈希码值。
     * 虽然Collection接口不会增加规定为Object.hashCode方法的常规协定，程序员应该注意的是，
     * 它覆盖Object.equals方法也必须重写Object.hashCode方法，以满足为Object.hashCode方法一般合同中的任何类。
     * 特别是c1.equals(c2)意味着c1.hashCode()==c2.hashCode() 。
     *
     * @return the hash code value for this collection
     *
     * @see Object#hashCode()
     * @see Object#equals(Object)
     */
    int hashCode();

    /**
     * 创建一个Spliterator在这个集合中的元素。 实现应该记录分配器报告的特征值。
     * 如果拼接器报告Spliterator.SIZED并且此集合不包含元素，则不需要报告此类特征值。
     * 应该通过可以返回更高效的拼接器的子类覆盖默认实现。
     * 为了保持stream()和parallelStream() }方法的预期懒惰行为，分频器应具有IMMUTABLE或CONCURRENT ，或者为late-binding 。
     * 如果这些都不实际，那么首要的类应该是描述绑定者所记录的绑定和结构性干扰的策略，并且应该覆盖stream()和parallelStream()方法以使用Supplier的Supplier创建流，如下所示：
     */
    @Override
    default Spliterator<E> spliterator() {
        return Spliterators.spliterator(this, 0);
    }

    /**
     * 返回一个顺序Stream与此集合作为其来源。
     * 当此方法应该重写spliterator()方法不能返回spliterator是IMMUTABLE ， CONCURRENT ，或后期绑定 。 （详见spliterator() ）
     * @return 默认的实现创建顺序 Stream从收集的 Spliterator 。
     * @since 1.8
     */
    default Stream<E> stream() {
        return StreamSupport.stream(spliterator(), false);
    }

    /**
     * 返回可能并行的Stream与此集合作为其来源。 该方法允许返回顺序流。
     * 当此方法应该重写spliterator()方法不能返回spliterator是IMMUTABLE ， CONCURRENT ，或后期绑定 。 （详见spliterator() ）
     * 默认的实现创建了一个平行 Stream从收集的 Spliterator 。
     * @return 一个可能平行 Stream移到该集合中的元素
     * @since 1.8
     */
    default Stream<E> parallelStream() {
        return StreamSupport.stream(spliterator(), true);
    }
}
